﻿using AppsGenerator.Utils;
using DBBuilder.DBDataStructure;
using System.IO;
using System.Reflection;
using CommonLogging;
using AppsGenerator.WebGenerators;
using AppsGenerator.WebGenerators.WebControllerGenerator;
using AppsGenerator.WebGenerators.WebRepositoryGenerator;
using AppsGenerator.WebGenerators.WebModelGenerator;
using AppsGenerator.WebGenerators.WebViewGenerator;

namespace AppsGenerator.Generators
{
    /// <summary>
    /// The generator is responsible for generating admin web pages
    /// </summary>
    public class WebGenerator: IGenerator
    {
        #region Fields

        /// <summary>
        /// Generator is responsible for generating controller components
        /// </summary>
        private readonly IWebComponentsGenerator _baseControllerGen;

        /// <summary>
        /// Generator is responsible for generating controller components
        /// </summary>
        private readonly IWebComponentsGenerator _adminControllerGen;

        /// <summary>
        /// Generator is responsible for generating repository components
        /// </summary>
        private readonly IWebComponentsGenerator _repositoryGen;

        /// <summary>
        /// Generator is responsible for generating model components
        /// </summary>
        private readonly IWebComponentsGenerator _adminModelGen;

        /// <summary>
        /// Generator is responsible for generating view model components
        /// </summary>
        private readonly IWebComponentsGenerator _viewModelGen;

        /// <summary>
        /// Generator is responsible for generating base view components
        /// </summary>
        private readonly IWebComponentsGenerator _baseViewGen;

        /// <summary>
        /// Generator is responsible for generating view components
        /// </summary>
        private readonly IWebComponentsGenerator _adminViewGen;

        /// <summary>
        /// The logger instance
        /// </summary>
        private readonly ILogger Logger = LoggerManager.GetLogger(typeof(WebGenerator).Name);

        #endregion

        #region Constructors

        /// <summary>
        /// Default constructor
        /// </summary>
        public WebGenerator()
        {
            var outputPath = Path.Combine(this.GetAppPath(), typeof(WebGenerator).Name);

            // Create folder Output if it does not exist 
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            // Constructor must be put right here
            this._baseControllerGen = IoC.Get<BaseControllerGenerator>();
            this._adminControllerGen = IoC.Get<AdminControllerGenerator>();
            this._adminModelGen = IoC.Get<AdminModelGenerator>();
            this._viewModelGen = IoC.Get<ViewModelGenerator>();
            this._repositoryGen = IoC.Get<RepositoryGenerator>();
            this._baseViewGen = IoC.Get<BaseViewGenerator>();
            this._adminViewGen = IoC.Get<AdminViewGenerator>();
        }
        
        #endregion

        #region Methods

        /// <summary>
        /// Get application path
        /// </summary>
        /// <returns></returns>
        private string GetAppPath()
        {
            return Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName;
        }

        /// <summary>
        /// Method to generate admin web pages components
        /// </summary>
        /// <param name="db">Data source for generating</param>
        public void Generate(DataBase db)
        {
            // Generate base controller components
            if (this._baseControllerGen != null)
            {
                this.Logger.Info("Generate BaseController --> Start");
                this._baseControllerGen.Generate(db);
                this.Logger.Info("Generate BaseController <-- End");
            }

            if (this._adminControllerGen != null)
            {
                // Generate controller components
                this.Logger.Info("Generate Controllers --> Start");
                this._adminControllerGen.Generate(db);
                this.Logger.Info("Generate Controllers <-- End");
            }

            if (this._repositoryGen != null)
            {
                // Generate repository components
                this.Logger.Info("Generate Repositories --> Start");
                this._repositoryGen.Generate(db);
                this.Logger.Info("Generate Repositories <-- End");
            }

            if (this._adminModelGen != null)
            {
                // Generate group models components
                this.Logger.Info("Generate Models --> Start");
                this._adminModelGen.Generate(db);
                this.Logger.Info("Generate Models <-- End");
            }

            if (this._viewModelGen != null)
            {
                // Generate group view of models components
                this.Logger.Info("Generate ViewModel --> Start");
                this._viewModelGen.Generate(db);
                this.Logger.Info("Generate ViewModel <-- End");
            }

            // Generate base controller components
            if (this._baseViewGen != null)
            {
                this.Logger.Info("Generate BaseView --> Start");
                this._baseViewGen.Generate(db);
                this.Logger.Info("Generate BaseView <-- End");
            }

            // Generate base controller components
            if (this._adminViewGen != null)
            {
                this.Logger.Info("Generate AdminView --> Start");
                this._adminViewGen.Generate(db);
                this.Logger.Info("Generate AdminView <-- End");
            }
        }

        #endregion
    }
}
